#include "cube.h"
#include "map.h"

//Cube constructor
//Sets the parent, location, and color of the new cube
Cube::Cube(Map *_parent, double newX, double newY, double newZ, int newSize, int newColor)
{
    //Set the parent, x, y, z, and color values
    this->setParent(_parent);
    this->cubeMap = _parent;
    x = newX;
    y = newY;
    z = newZ;
    size = newSize;
    color = newColor;
    camDistance = 0;
}

int * Cube::makePolygon(int side)
{
    double differenceX = x - this->cubeMap->x;
    double differenceY = y - this->cubeMap->y;       

    //Steps for creating the two main data points needed for calculating cube display
    //1) Offset and scale grow smaller with distance as cubes converge
    //2) Add the offset to the center of the screen (the vanishing point)
    //3) Back of the cube is farther back along the z-axis than the front

    double frontCenterX = ((this->x - this->cubeMap->x) * (this->cubeMap->parentWidget()->width() / 30.0)) /
                          ((this->z + 24) / 25.0) + (this->cubeMap->parentWidget()->width() / 2.0);
    double frontCenterY = ((this->y - this->cubeMap->y) * (this->cubeMap->parentWidget()->height() / 30.0)) /
                          ((this->z + 24) / 25.0) + (this->cubeMap->parentWidget()->height() / 2.0);
    double backCenterX = ((this->x - this->cubeMap->x) * (this->cubeMap->parentWidget()->width() / 30.0)) /
                          ((this->z + 10 + 24) / 25.0)+ (this->cubeMap->parentWidget()->width() / 2.0);
    double backCenterY = ((this->y - this->cubeMap->y) * (this->cubeMap->parentWidget()->height() / 30.0)) /
                          ((this->z + 10 + 24) / 25.0) + (this->cubeMap->parentWidget()->height() / 2.0);

    //Use that data to calculate the positioins of the cube's eight vertices
    int vertices[16];
    double frontOffset = (this->size * (this->cubeMap->parentWidget()->width() / 30.0)) /
                         (2 * (this->z + 24) / 25.0);
    double backOffset = (this->size * (this->cubeMap->parentWidget()->height() / 30.0)) /
                        (2 * (this->z + 10 + 24) / 25.0);


    //Front vertices
    vertices[0] = frontCenterX - frontOffset;
    vertices[1] = frontCenterY - frontOffset;
    vertices[2] = frontCenterX + frontOffset;
    vertices[3] = frontCenterY - frontOffset;
    vertices[4] = frontCenterX + frontOffset;
    vertices[5] = frontCenterY + frontOffset;
    vertices[6] = frontCenterX - frontOffset;
    vertices[7] = frontCenterY + frontOffset;
    //Back vertices
    vertices[8] = backCenterX - backOffset;
    vertices[9] = backCenterY - backOffset;
    vertices[10] = backCenterX + backOffset;
    vertices[11] = backCenterY - backOffset;
    vertices[12] = backCenterX + backOffset;
    vertices[13] = backCenterY + backOffset;
    vertices[14] = backCenterX - backOffset;
    vertices[15] = backCenterY + backOffset;


    int *polyVerts;
    polyVerts = new int[8];
    switch (side)
    {
    //Get the front of the cube
    case 0:
        polyVerts[0] = (vertices[0]);
        polyVerts[1] = (vertices[1]);
        polyVerts[2] = (vertices[2]);
        polyVerts[3] = (vertices[3]);
        polyVerts[4] = (vertices[4]);
        polyVerts[5] = (vertices[5]);
        polyVerts[6] = (vertices[6]);
        polyVerts[7] = (vertices[7]);
        break;
    //Get the side of the cube
    case 1:
        //Left side of the cube
        if(differenceX > 0)
        {
            polyVerts[0] = (vertices[0]);
            polyVerts[1] = (vertices[1]);
            polyVerts[2] = (vertices[6]);
            polyVerts[3] = (vertices[7]);
            polyVerts[4] = (vertices[14]);
            polyVerts[5] = (vertices[15]);
            polyVerts[6] = (vertices[8]);
            polyVerts[7] = (vertices[9]);
        }
        //Right side of the cube
        else
        {
            polyVerts[0] = (vertices[2]);
            polyVerts[1] = (vertices[3]);
            polyVerts[2] = (vertices[4]);
            polyVerts[3] = (vertices[5]);
            polyVerts[4] = (vertices[12]);
            polyVerts[5] = (vertices[13]);
            polyVerts[6] = (vertices[10]);
            polyVerts[7] = (vertices[11]);
        }

        break;
    //Get the top/bottom of the cube
    case 2:
        //Bottom
        if(differenceY < 0)
        {
            polyVerts[0] = (vertices[6]);
            polyVerts[1] = (vertices[7]);
            polyVerts[2] = (vertices[4]);
            polyVerts[3] = (vertices[5]);
            polyVerts[4] = (vertices[12]);
            polyVerts[5] = (vertices[13]);
            polyVerts[6] = (vertices[14]);
            polyVerts[7] = (vertices[15]);

        }
        //Top of the cube
        else
        {
            polyVerts[0] = (vertices[0]);
            polyVerts[1] = (vertices[1]);
            polyVerts[2] = (vertices[2]);
            polyVerts[3] = (vertices[3]);
            polyVerts[4] = (vertices[10]);
            polyVerts[5] = (vertices[11]);
            polyVerts[6] = (vertices[8]);
            polyVerts[7] = (vertices[9]);
        }
        break;
    }
    return polyVerts;
}

void Cube::zUpdate()
{
    z -= cubeMap->speed;
}

void Cube::visUpdate()
{
    if(z < 800) //first z depends on distance fade settings in mainwindow paintevent
        visible = true;
    else
        visible = false;
}

bool Cube::crashTest()
{
    if(z < 5)
    {
        if(x - size/2.0 < cubeMap->x + cubeMap->shipWidth/2 &&
           x + size/2.0 > cubeMap->x - cubeMap->shipWidth/2 &&
           y - size/2.0 < cubeMap->y + cubeMap->shipOffset + cubeMap->shipWidth/2.0 &&
           y + size/2.0 > cubeMap->y + cubeMap->shipOffset - cubeMap->shipWidth/2.0)
           return true;
        else
            return false;
    }
    else
        return false;
}
